<template>
  <el-select
    v-model="data"
    v-bind="$attrs"
    :filter-method="querySearch"
    :loading="loading"
    :select-when-unmatched="true"
    highlight-first-item
    class="search-select"
    clearable
    filterable
    default-first-option
    placeholder="请输入"
    @change="handleSelect"
    @clear="handleClear"
    @visible-change="handleVisibleChange"
    v-on="$listeners">
    <el-option
      v-for="item in items"
      :key="item[field.value]"
      :label="item[field.name]"
      :value="item[field.value]">
      <div class="name">{{ item[field.name] }}</div>
      <span class="value">{{ item[field.value] }}</span>
    </el-option>
  </el-select>
</template>

<script>
import request from '@/utils/request'

export default {
  name: 'SearchSelect',
  props: {
    dispatch: {
      type: String,
      default: ''
    },
    value: {
      type: String,
      default: ''
    },
    options: {
      type: Array,
      default: () => { return [] }
    },
    url: {
      type: Object,
      default: () => {
        return {
          path: '',
          params: ''
        }
      },
      required: true
    },
    field: {
      type: Object,
      default: () => {
        return {
          name: 'name',
          value: 'value'
        }
      }
    }
  },
  data() {
    return {
      items: [],
      data: this.value,
      timeout: null,
      loading: false
    }
  },
  watch: {
    value() {
      this.data = this.value
      this.$emit('update:value', this.data)
      this.loadData(this.data)
    },
    options() {
      this.items = this.options
      this.$emit('update:options', this.options)
    },
    data() {
      this.$emit('update:value', this.data)
    }
  },
  mounted() {
  },
  methods: {
    querySearch(query) {
      if (query !== '') {
        this.loading = true
        clearTimeout(this.timeout)
        this.timeout = setTimeout(() => {
          this.loadData(query).then(_ => {
            console.log(this.items)
            this.items = this.items.filter(this.createFilter(query))
            this.loading = false
          })
        }, 300)
      }
    },
    createFilter(query) {
      return (item) => {
        return (item[this.field.value].toLowerCase().indexOf(query.toLowerCase()) >= 0 ||
            item[this.field.name].toLowerCase().indexOf(query.toLowerCase()) >= 0)
      }
    },
    loadData(query, callback) {
      const postData = {}
      postData[this.field.value] = query
      postData[this.field.name] = query
      const params = Object.assign({ page: 1, limit: 10 }, postData, this.url.params)
    if (this.dispatch) {
      this.$store.dispatch(this.dispatch, params).then(data => {
        this.items = data
      })
    }
    else if (this.url && this.items.length <= 1) {
        return request({
          url: this.url.path,
          method: 'get',
          params: params
        }).then((response) => {
          this.items = response.result.items
          if (callback) callback()
        })
      }
    },
    handleVisibleChange(value) {
      if (value && this.items.length <= 1) {
        const defaultItem = this.items.length > 0 ? this.items[0] : null
        this.loadData('', () => {
          if (defaultItem) {
            const index = this.items.findIndex((value, index) => { return value === defaultItem[this.field.value] })
            if (index >= 0) {
              this.items.splice(index, 1, defaultItem)
            } else {
              this.items.splice(0, 1, defaultItem)
            }
          }
        })
      }
    },
    handleSelect(value) {
      this.data = value
      this.$emit('update:value', value)
    },
    handleClear() {
      this.data = ''
      this.items = []
      this.$emit('update:value', '')
    }
  }
}
</script>

<style lang="scss" scoped>
  .search-select {
      line-height: normal;
      .name {
        font-size: 14px;
        text-overflow: ellipsis;
        overflow: hidden;
      }
      .value {
        font-size: 12px !important;
        color: #b4b4b4 !important;
      }
      .highlighted .value {
        color: #ddd;
      }
  }
</style>
